/*
 *
 *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  SPDX-License-Identifier: Apache-2.0
 *
 */
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { ChainCreateRequest, ChainModes, StakeItem } from 'src/common/apis/chains/interface';
import { Control, Controller, useForm, UseFormSetValue, UseFormTrigger, useWatch } from 'react-hook-form';
import { Form, H3, Input, Justify, Select } from 'tea-component';
import formUtils, { getStatus } from 'src/utils/form-utils';
import { useFetchCertUserList } from 'src/common/apis/chains/hooks';

interface StakeOpProps {
  selectedNodes: ChainCreateRequest['Nodes'];
  selectedChainMode: ChainModes;
  control: Control;
  isSubmitted: boolean;
  isValidating: boolean;
  setValue: UseFormSetValue<any>;
  trigger: UseFormTrigger<any>;
}
// 选取不同类型节点节点
export default function StakeOp(props: StakeOpProps) {
  const [validList, setValidList] = useState<boolean[]>([]);
  const { run: getCertUserList, list: adminList } = useFetchCertUserList();
  const stakeMinCount = useWatch({ name: 'StakeMinCount', control: props.control });
  const stakes: ChainCreateRequest['Stakes'] = useWatch({ name: 'Stakes', control: props.control });
  const hasSelectAdmin: string[] = useMemo(() => (stakes ? stakes.map((item) => item.RemarkName) : []), [stakes]);
  useEffect(() => {
    props.setValue(
      'Stakes',
      props.selectedNodes.reduce((res, item) => {
        const ls = item?.NodeList.map((node) => {
          const obj = stakes?.filter((item) => item.NodeName === node.NodeName)[0];
          if (obj) {
            obj.Count = obj?.Count ? Number(obj.Count) : undefined;
          }
          return (
            obj || {
              NodeName: node.NodeName,
              RemarkName: '',
              Count: undefined,
            }
          );
        });
        return res?.concat(ls);
      }, [] as StakeItem[]),
    );
  }, [props.selectedNodes]);

  const adminOptions = useMemo(
    () =>
      adminList.map((admin) => ({
        value: admin.UserName,
        disabled: hasSelectAdmin.indexOf(admin.UserName) > -1,
      })),
    [adminList, hasSelectAdmin],
  );

  useEffect(() => {
    getCertUserList({
      ChainMode: props.selectedChainMode,
    });
  }, []);
  const updateValidList = useCallback(
    (bl, index) => {
      validList[index] = bl;
      setValidList(validList);
      props.trigger('Stakes');
    },
    [validList],
  );

  return (
    <>
      <Form layout="fixed" fixedLabelWidth="90px">
        <Justify left={<H3>Stake配置</H3>} className={'tea-mb-5n'} />
        <Controller
          name="StakeMinCount"
          control={props.control}
          rules={{
            required: true,
            validate: (value: string) => {
              if (!/^\d*/.test(value)) {
                return '请输入有效数字';
              }
              if (Number(value) <= 0) {
                return '请输入有效最小Stake数量';
              }
              return undefined;
            },
          }}
          render={({ field, fieldState }) => (
            <Form.Item
              label="最小Stake数量"
              className={'node-selector'}
              status={formUtils.getStatus({
                fieldState,
                isSubmitted: props.isSubmitted,
                isValidating: props.isValidating,
              })}
              message={fieldState.error?.message}
            >
              <Input {...field} placeholder="请输入最小Stake数量" />
            </Form.Item>
          )}
        ></Controller>
      </Form>
      <Controller
        name="Stakes"
        control={props.control}
        rules={{
          validate: () => {
            if (validList.filter((item) => item !== true).length) {
              return '请输入完整并正确的Stakes信息';
            }
            return undefined;
          },
        }}
        render={({ field }) => (
          <div style={{ marginTop: 10 }}>
            {stakes?.map((item, index) => (
              <StakeSet
                key={item.NodeName}
                adminOptions={adminOptions}
                StakeMinCount={Number(stakeMinCount)}
                stake={item}
                updateValid={(isValid) => {
                  updateValidList(isValid, index);
                }}
                onChange={(sk: StakeItem) => {
                  stakes[index] = sk;
                  field.onChange(stakes);
                }}
              />
            ))}
          </div>
        )}
      ></Controller>
    </>
  );
}

function StakeSet({
  stake,
  StakeMinCount,
  adminOptions,
  onChange,
  updateValid,
}: {
  StakeMinCount: number;
  adminOptions: any[];
  stake: any;
  onChange: (sk: StakeItem) => void;
  updateValid: (bl: boolean) => void;
}) {
  const {
    control,
    trigger,
    formState: { isValidating, isSubmitted, isValid },
  } = useForm({
    mode: 'onBlur',
    defaultValues: stake,
  });
  const count = useWatch({ name: 'Count', control });
  const remarkName = useWatch({ name: 'RemarkName', control });
  useEffect(() => {
    const tk = {
      ...stake,
      Count: count ? Number(count) : undefined,
      RemarkName: remarkName,
    };
    onChange(tk);
  }, [count, remarkName]);
  useEffect(() => {
    updateValid(isValid);
  }, [isValid]);
  useEffect(() => {
    trigger('Count');
  }, [StakeMinCount]);
  return (
    <Form layout="inline" fixedLabelWidth={90}>
      <Form.Item key={stake.NodeName} label={<div className={'chain-deploy-node-name'}>{stake.NodeName}</div>} />
      <Controller
        control={control}
        name="RemarkName"
        rules={{
          required: true,
        }}
        render={({ field, fieldState }) => (
          <Form.Item
            status={getStatus({
              fieldState,
              isSubmitted,
              isValidating,
            })}
            message={fieldState.error?.message}
          >
            <Select options={adminOptions} placeholder="请选择链账户" {...field} />
          </Form.Item>
        )}
      ></Controller>
      <Controller
        control={control}
        name="Count"
        rules={{
          validate: (val) => {
            if (isNaN(StakeMinCount) || val === undefined) {
              return undefined;
            }
            if (!/^\d*$/.test(`${val}`)) {
              return '请输入有效数字';
            }
            if (val && val < StakeMinCount) {
              return 'Stake数量不可小于最小Stake数';
            }
            return undefined;
          },
        }}
        render={({ field, fieldState }) => (
          <Form.Item
            status={getStatus({
              fieldState,
              isSubmitted,
              isValidating,
            })}
            message={fieldState.error?.message}
          >
            <Input style={{ marginLeft: 10 }} placeholder="请输入Stake数量" {...field} />
          </Form.Item>
        )}
      ></Controller>
    </Form>
  );
}
